using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


using TVT.UI.Helpers;
using TVT.Common.Exceptions;
using System.Collections.Generic;
using TVT.Common.Helpers;
using TVT.BizLayer.Entities;

using System.Transactions;

namespace TVT.UI.UserControls
{
    public partial class CreateUpdateUser : System.Web.UI.UserControl
    {       
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                LoadRoles();
                SetPermissions();
                ViewState[WellKnownKeys.UserAliasKey] = new List<UserAlias>();
            }
        }
       
        private void HideItemsWhenMasterAdmin() 
        {
            ddlRoles.Enabled = true;
                
        }
       
        private void SetPermissions()
        {
            if(Roles.IsUserInRole(WellKnownKeys.AdministratorRolKey))
            {
                ddlRoles.Enabled = true;
                ddlRoles.SelectedValue = WellKnownKeys.AdministratorRolKey;
                HideItemsWhenMasterAdmin();
            }
            else
            {
                ddlRoles.SelectedValue = WellKnownKeys.UserRolKey;
                ddlRoles.Visible = Roles.IsUserInRole(WellKnownKeys.UserRolKey);
            }
        }

        public void Cancel()
        {
            txtFirstName.Text = "";
            Email.Text = "";
            UserName.Text = "";
            txtIM.Text = "";
            txtLastName.Text = "";
            txtOldPassword.Text = "";
            txtPhone1.Text = "";
            updateUsersPanel.Update();
        }

        private void LoadRoles()
        {
            string[] roles = Roles.GetAllRoles();
            ddlRoles.DataSource = roles;
            ddlRoles.DataBind();            
        }

        protected void DoCancel(object sender, EventArgs e)
        {
            ViewState[WellKnownKeys.UserAliasKey] = new List<UserAlias>();
            ViewState["IdUser"] = null;
            Cancel();
            Response.Redirect(Request.Url.AbsolutePath);
        }

        protected void CreateUser(object sender, EventArgs e)
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                try
                {
                    MembershipCreateStatus status;
                    bool isEdit;
                    MembershipUser memUser = Membership.GetUser(UserName.Text);

                    if (memUser == null)
                    {
                        isEdit = false;
                        memUser = Membership.CreateUser(UserName.Text, Password.Text, Email.Text, null, null, true, out status);
                        switch (status)
                        {
                            case MembershipCreateStatus.DuplicateEmail:
                                lblMessage.Visible = true;
                                lblMessage.Text = MembershipCreateStatus.DuplicateEmail.ToString();
                                return;

                            case MembershipCreateStatus.InvalidPassword:
                                lblMessage.Visible = true;
                                lblMessage.Text = MembershipCreateStatus.InvalidPassword.ToString();
                                return;

                            case MembershipCreateStatus.InvalidEmail:
                                lblMessage.Visible = true;
                                lblMessage.Text = MembershipCreateStatus.InvalidEmail.ToString();
                                return;
                        }
                    }
                    else
                    {
                        isEdit = true;
                        memUser.Email = Email.Text;
                        try
                        {
                            Membership.UpdateUser(memUser);
                        }
                        catch (System.Configuration.Provider.ProviderException ex)
                        {
                            transaction.Dispose();
                            lblMessage.Visible = true;
                            lblMessage.Text = MembershipCreateStatus.DuplicateEmail.ToString();
                            return;
                        }
                        if (cbxChangePassword.Checked)
                        {
                            if (Password.Text.Length < 7)
                            {
                                lblMessage.Visible = true;
                                lblMessage.Text = Resources.IncorrectPasswordLength;
                                return;
                            }
                            if (!memUser.ChangePassword(txtOldPassword.Text, Password.Text))
                            {
                                transaction.Dispose();
                                lblMessage.Visible = true;
                                lblMessage.Text = Resources.NewPasswordIncorrect;
                                return;
                            }
                        }
                        lblMessage.Visible = true;
                        if (txtOldPassword.Text == "")
                        {
                            lblMessage.Text = MembershipCreateStatus.DuplicateUserName.ToString();
                        }
                        else
                        {
                            lblMessage.Text = Resources.IncorrectPassword;
                        }

                    }

                    if (memUser != null)
                    {
                        string[] s = Roles.GetRolesForUser(memUser.UserName);

                        if (s.Length != 0)
                        {
                            Roles.RemoveUserFromRole(memUser.UserName, s[0]);
                        }

                        Roles.AddUserToRole(memUser.UserName, ddlRoles.SelectedValue);
                        User user = new User();
                        user.FirstName = txtFirstName.Text;
                        user.LastName = txtLastName.Text;
                        user.Im = txtIM.Text;
                        user.Phone1 = txtPhone1.Text;

                        user.UserId = (Guid)memUser.ProviderUserKey;

                        List<UserAlias> userAlias = new List<UserAlias>();
                        if (ViewState[WellKnownKeys.UserAliasKey] != null)
                            userAlias = (List<UserAlias>)ViewState[WellKnownKeys.UserAliasKey];

                        user.Alias = userAlias;

                        TVT.BizLayer.Entities.UserProfile userProfile = new TVT.BizLayer.Entities.UserProfile();
                        userProfile.High = int.Parse(txtHigh.Text);
                        userProfile.Weight = int.Parse(txtWeight.Text);
                        userProfile.Male = (rblSex.SelectedIndex == 1);
                        switch (rblLookingFor.SelectedIndex)
                        { 
                            case 0:
                                userProfile.Likes = Enumerators.Likes.Girls;
                                break;
                            case 1:
                                userProfile.Likes = Enumerators.Likes.Boys;
                                break;
                            case 2:
                                userProfile.Likes = Enumerators.Likes.Both;
                                break;
                        }
                        userProfile.BirthDate = dpBirthDate.SelectedDate;
                        user.UserProfile = userProfile;

                        user.Save();

                        transaction.Complete();
                        Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
                        FormsAuthentication.SetAuthCookie(memUser.UserName, true);
                        Response.Redirect("~/UserProfile.aspx");
                    }
                    else
                    {
                        transaction.Dispose();
                        lblMessage.Visible = true;
                        lblMessage.Text = Resources.ErrorMessage;
                    }
                    
                }
                catch (FunctionalException ex)
                {
                    transaction.Dispose();
                    lblMessage.Visible = true;
                    lblMessage.Text = ex.Message;
                } 
                
            }
        }

        protected void ShowItemsByRol()
        {
          switch (ddlRoles.SelectedItem.Value)
            {
                case (WellKnownKeys.GuestRolKey):
                case (WellKnownKeys.UserRolKey):
                    if (!Roles.IsUserInRole(WellKnownKeys.AdministratorRolKey))
                    {
                        if (Roles.IsUserInRole(WellKnownKeys.GuestRolKey))
                        {
                        }
                    }
                    break;
                case (WellKnownKeys.AdministratorRolKey):
                    HideItemsWhenMasterAdmin();
                    break;
            }
        }

        protected void ddlRoles_SelectedIndexChanged(object sender, EventArgs e)
        {
            ShowItemsByRol();
        }

        public void EditUser(Guid userId)
        {
            ViewState["IdUser"] = userId;
            User user = User.Find(userId);
            txtFirstName.Text = user.FirstName;
            txtLastName.Text = user.LastName;
            txtIM.Text = user.Im;
            txtPhone1.Text = user.Phone1;
            UserName.Text = user.UserName;
            //txtOldPassword.Text = Membership.GetUser(user.UserId).GetPassword();
            Email.Text = user.Email;

            ddlRoles.SelectedValue = (Roles.GetRolesForUser(user.UserName))[0].ToString();

            ShowItemsByRol();

            UserName.Enabled = false;
            divOldPassword.Visible = false;
            divChangePassword.Visible = true;
            divNewPassword.Visible = false;
            
            ViewState[WellKnownKeys.UserAliasKey] = user.Alias;
            SortTable();
            
            updateUsersPanel.Update();
        }

        protected void ChangePassword(object sender, EventArgs e)
        {
            if (cbxChangePassword.Checked)
            {                                  
                divNewPassword.Visible = true;
                txtOldPassword.Text = Membership.GetUser(UserName.Text).GetPassword();
                divOldPassword.Visible = true;
            }
            else
            {                                
                divNewPassword.Visible = false;
                divOldPassword.Visible = false;
            }            
        }


        protected void AddUsrName(object sender, EventArgs e)
        {
            lblUsrNameMessage.Visible = false;
            
            if (ViewState[WellKnownKeys.UserAliasKey] == null)
                ViewState[WellKnownKeys.UserAliasKey] = new List<UserAlias>();
            
            if( txtUsrName.Text != "" )
            {
                Enumerators.Platform platform = (Enumerators.Platform)Enum.ToObject(typeof(Enumerators.Platform), Int32.Parse(ddlUsrNamePlatform.SelectedValue));
                UserAlias newAlias = new UserAlias();
                newAlias.Name = txtUsrName.Text;
                newAlias.Platform = platform;
                List<UserAlias> userAlias = (List<UserAlias>)ViewState[WellKnownKeys.UserAliasKey];
                userAlias.Add(newAlias);

                SortTable();

                CleanUserAlias();
            }
            else
            {
                lblUsrNameMessage.Visible = true;
                lblUsrNameMessage.Text = "You must insert name field.";
            }
           
        }
        protected void CancelAddUsrName(object sender, EventArgs e)
        {
            CleanUserAlias();
        }

        private void CleanUserAlias()
        {
            txtUsrName.Text = "";
            lblUsrNameMessage.Text = "";
        }
        protected void gvUsrName_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            string deleteArgument = e.CommandArgument.ToString();

            if (e.CommandName != "Sort")
            {
                List<UserAlias> userAlias = (List<UserAlias>)ViewState[WellKnownKeys.UserAliasKey];
                for (int index = 0; index < userAlias.Count; index++)
                {
                    if (deleteArgument == userAlias[index].GetKey())
                    {
                        userAlias.RemoveAt(index);
                        break;
                    }
                }
                SortTable();
            }
        }

        protected void gvUsrName_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            StylesApplier stylesApplier = new StylesApplier();
            try
            {
                stylesApplier.GridViewStyle(e.Row);
                string deleteArgument = "";
                string platform = "";
                string alias = "";


                if (e.Row.DataItem != null)
                {
                    if (e.Row.DataItem.GetType() == typeof(UserAlias))
                    {
                        UserAlias userAlias = ((UserAlias)(e.Row.DataItem));
                        platform = userAlias.Platform.ToString();
                        alias = userAlias.Name;
                        deleteArgument = alias;
                    }
                    else
                    {
                        DataRow dataRow = ((System.Data.DataRowView)(e.Row.DataItem)).Row;
                        Enumerators.Platform platformAlias = (Enumerators.Platform)Enum.ToObject(typeof(Enumerators.Platform), (int)dataRow["IdPlatform"]);
                        
                        platform = platformAlias.ToString();
                        alias = dataRow["Name"].ToString();
                        deleteArgument = UserAlias.MakeKey((int)dataRow["Id"], (string)dataRow["Name"], (Guid)dataRow["IdUser"], platformAlias);
                    }
                    
                    Label lblPlatformName = (Label)e.Row.FindControl("lblUsrNamePlatformName");
                    lblPlatformName.Text = platform;

                    Label lblUserAlias = (Label)e.Row.FindControl("lblUsrNameGrid");
                    lblUserAlias.Text = alias;

                    

                    ImageButton lbtnDelete = (ImageButton)e.Row.FindControl("lbtnDelete");
                    if (lbtnDelete != null)
                        lbtnDelete.CommandArgument = deleteArgument;
                }
            }
            catch (Exception ex)
            {
                ExceptionLogger.HandleException(ex);
            }
        }

        protected void OnSortingGvUserAlias(object sender, GridViewSortEventArgs e)
        {
            string sort = " ASC";

            if (ViewState["sortDirection"] == null)
                ViewState["sortDirection"] = SortDirection.Ascending;
            else
            {
                if ((SortDirection)ViewState["sortDirection"] == SortDirection.Ascending)
                {
                    ViewState["sortDirection"] = SortDirection.Descending;
                    sort = " DESC";
                }
                else
                {
                    ViewState["sortDirection"] = SortDirection.Ascending;
                    sort = " ASC";
                }
            }
            DoSortTable( e.SortExpression + sort );

            
        }

        private void ListUserAlias()
        {

        }

        private DataTable GetDataTableFromUsersAliasList(List<UserAlias> users)
        {
            DataTable dataTable = new DataTable();


            dataTable.Columns.Add("Id");
            dataTable.Columns["Id"].DataType = typeof(int);

            dataTable.Columns.Add("Name");
            dataTable.Columns["Name"].DataType = typeof(string);
            
            dataTable.Columns.Add("IdUser");
            dataTable.Columns["IdUser"].DataType = typeof(Guid);
            
            dataTable.Columns.Add("IdPlatform");
            dataTable.Columns["IdPlatform"].DataType = typeof(int);

            dataTable.Columns.Add("Platform");
            dataTable.Columns["Platform"].DataType = typeof(string);
            
                       
            DataRow dataRow;

            foreach (UserAlias userAlias in users)
            {
                dataRow = dataTable.NewRow();

                dataRow["Id"] = userAlias.Id;
                dataRow["IdUser"] = userAlias.IdUser;
                dataRow["IdPlatform"] = userAlias.Platform;
                dataRow["Platform"] = userAlias.Platform.ToString();
                dataRow["Name"] = userAlias.Name;
                
                dataTable.Rows.Add(dataRow);
            }

            return dataTable;
        }

        private void SortTable()
        {
            if (ViewState["sortDirection"] == null)
                ViewState["sortDirection"] = SortDirection.Ascending;
            if ((SortDirection)ViewState["sortDirection"] == SortDirection.Ascending)
                DoSortTable("Platform ASC");
            else
                DoSortTable("Platform DESC");
                
        }

        private void DoSortTable(string sortExpression)
        {
            List<UserAlias> userAlias = (List<UserAlias>)ViewState[WellKnownKeys.UserAliasKey];
            DataTable dataTable = GetDataTableFromUsersAliasList(userAlias);

            if (dataTable != null)
            {
                DataView dataView = new DataView(dataTable);

                dataView.Sort = sortExpression;
                ViewState["SortExpression"] = sortExpression;
                gvUsrName.DataSource = dataView;
                gvUsrName.DataBind();
            }
        }
    }
}